#pragma once

#include "../umlmodel_global.h"

#include <memory>
#include <vector>

#include "Dependency.h"

using std::make_shared;
using std::shared_ptr;
using std::vector;

namespace uml {
class OpaqueExpression;

/// <summary>
/// Abstraction
/// An Abstraction is a Relationship that relates two Elements or sets of Elements
/// that represent the same concept at different levels of abstraction or from
/// different viewpoints.
/// </summary>
class UMLMODEL_EXPORT Abstraction : public Dependency {

public: // Constructors and destructors
    explicit Abstraction(const QString& umlType="uml::Abstraction");

public: // JsonSerializable override
    void fromJson(const QJsonObject& json, QStringList& errorList) override;
    void toJson(QJsonObject& json) override;

public: // Properties
    /// <summary>
    /// mapping getter
    /// An OpaqueExpression that states the abstraction relationship between the
    /// supplier(s) and the client(s). In some cases, such as derivation, it is usually
    /// formal and unidirectional; in other cases, such as trace, it is usually informal
    /// and bidirectional. The mapping expression is optional and may be omitted if the
    /// precise relationship between the Elements is not specified.
    /// </summary>
    shared_ptr<OpaqueExpression> mapping() const;

    /// <summary>
    /// mapping setter
    /// An OpaqueExpression that states the abstraction relationship between the
    /// supplier(s) and the client(s). In some cases, such as derivation, it is usually
    /// formal and unidirectional; in other cases, such as trace, it is usually informal
    /// and bidirectional. The mapping expression is optional and may be omitted if the
    /// precise relationship between the Elements is not specified.
    /// </summary>
    void setMapping(shared_ptr<OpaqueExpression> value);

private: // Fields
    /// <summary>
    /// mapping
    /// An OpaqueExpression that states the abstraction relationship between the
    /// supplier(s) and the client(s). In some cases, such as derivation, it is usually
    /// formal and unidirectional; in other cases, such as trace, it is usually informal
    /// and bidirectional. The mapping expression is optional and may be omitted if the
    /// precise relationship between the Elements is not specified.
    /// </summary>
    shared_ptr<OpaqueExpression> mapping_;

};

} // namespace uml
